"""
 Wrapper class for yahoo finance quote API.
 Reference:
 http://code.google.com/p/yahoo-finance-managed/wiki/csvQuotesDownload
 
 Created on May, 2012
 @author: Xiaoyuan XU
"""

import urllib

from StringIO import StringIO
from google.appengine.ext import db #@UnresolvedImport


class QuoteRecord(db.Model):
    timestamp = db.DateTimeProperty(auto_now_add=True)
    quoteData = db.StringProperty(multiline=True)
    symbol = db.StringProperty()        
    
class YahooFinance:
    
    def __request(self, symbol, stat):
        try:
            url = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (symbol,
                                                                       stat)
            return urllib.urlopen(url).read().strip()
        except IOError:
            print "Can't connect to Yahoo server"
            raise
        except BaseException as excep:
            print "Unknown Error in YahooFinance.__request %s" % excep
            raise

    """
    Create a quote record from the response and put in data store
    """
    def __create_quoterecord(self, response):
        r = QuoteRecord()
        
        # To save write operations, we write the response as a string directly, 
        # although ideally, we should write out every property.
        # But to make query easier later, we extract the symbol name and store 
        # it as a separate property 
        r.quoteData = response
        values = response.split(',')
        r.symbol = values[0].strip('"')
        
        print "create quote record: " + response
        
        return r 
    
    """
    Query YahooFiance for the current quote data
    symbols: the list of symbol names
    properties: the property tag string
    """
    def query_currentquotes(self, symbols, properties): 
        if isinstance(symbols, (list, tuple)):
            symbols = ','.join(symbols)
        
        response = self.__request(symbols, properties)
        
        quoteList = response.splitlines();
                
        for quoteData in quoteList:
            r = self.__create_quoterecord(quoteData)
            r.put()
        
    """
    Retrieve the quote record data from the data store
    """    
    def get_quoterecord(self, symbol): 
        quoteRecords = db.GqlQuery("SELECT * FROM QuoteRecord" + 
                                   " WHERE symbol = '\"" + 
                                   str(symbol).upper() +
                                   "\"' ORDER BY timestamp DESC")
        stdout = StringIO()

        # write out the header
        stdout.write('timestamp,s,a,b,c,o,g,h,v,l1,j,j5,j6,k,k4,k5,j3,b4\r\n')

        for quoteRecord in quoteRecords:
            stdout.writelines(str(quoteRecord.timestamp) + "," + 
                              quoteRecord.quoteData + "\r\n")
            
        return stdout.getvalue()
    
    """
    Validate quote records
        - Remove non-weekday record
        - Remove the extra " character in the symbol name
    """                  
    def validate_quoterecord(self, quoteRecords): 
        
        for quoteRecord in quoteRecords:
            
            # remove non-weekday record
            if quoteRecord.timestamp.weekday() >= 5:
                quoteRecord.delete()
                
            else:
                # remove the extra " character in the symbol name
                s = str(quoteRecord.symbol)
                if s.startswith('"'):
                    quoteRecord.symbol = s.strip('"')
                    quoteRecord.put()